package com.autoglm.android.core.execution

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.content.Context
import android.content.Intent
import android.graphics.Path
import android.graphics.Rect
import android.media.projection.MediaProjection
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.view.accessibility.AccessibilityNodeInfo
import com.autoglm.android.core.accessibility.ScreenAnalyzer
import com.autoglm.android.core.models.ExecutionStep
import com.autoglm.android.core.models.TaskExecutionPlan
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.Thread.sleep

/**
 * 跨应用执行引擎，负责执行任务计划中的步骤
 */
class CrossAppExecutionEngine(
    private val context: Context,
    private val accessibilityService: AccessibilityService,
    private val screenAnalyzer: ScreenAnalyzer,
    private val taskStateManager: TaskStateManager,
    private val mediaProjection: MediaProjection? = null
) {
    companion object {
        private const val TAG = "CrossAppExecution"
        private const val DEFAULT_TIMEOUT = 5000L // 默认超时时间5秒
        private const val DEFAULT_WAIT_AFTER_ACTION = 500L // 每个操作后默认等待时间
    }
    
    private val mainHandler = Handler(Looper.getMainLooper())
    private val coroutineScope = CoroutineScope(Dispatchers.Default)
    
    // 执行状态流
    private val _executionState = MutableStateFlow<ExecutionState>(ExecutionState.Idle)
    val executionState: StateFlow<ExecutionState> = _executionState
    
    /**
     * 执行任务计划
     * 
     * @param plan 要执行的任务计划
     * @return 包含执行状态和结果的Flow
     */
    fun executeTaskPlan(plan: TaskExecutionPlan): Flow<ExecutionState> = flow {
        // 更新状态为准备中
        _executionState.update { ExecutionState.Preparing(plan) }
        emit(ExecutionState.Preparing(plan))
        
        // 检查权限
        if (!checkRequiredPermissions(plan.requiredPermissions)) {
            val missingPermissions = getMissingPermissions(plan.requiredPermissions)
            _executionState.update { ExecutionState.PermissionsRequired(missingPermissions) }
            emit(ExecutionState.PermissionsRequired(missingPermissions))
            return@flow
        }
        
        // 初始化任务状态
        taskStateManager.initializeTask(plan)
        
        // 更新状态为执行中
        _executionState.update { ExecutionState.Executing(plan, 0, plan.steps.size) }
        emit(ExecutionState.Executing(plan, 0, plan.steps.size))
        
        // 开始执行步骤
        var stepIndex = 0
        var currentStep: ExecutionStep
        
        while (stepIndex < plan.steps.size) {
            currentStep = plan.steps[stepIndex]
            
            // 更新当前执行的步骤
            _executionState.update { 
                if (it is ExecutionState.Executing) {
                    it.copy(currentStepIndex = stepIndex + 1)
                } else {
                    ExecutionState.Executing(plan, stepIndex + 1, plan.steps.size)
                }
            }
            emit(_executionState.value)
            
            // 执行当前步骤
            val stepResult = executeStep(currentStep)
            
            if (stepResult) {
                // 步骤执行成功，继续下一步
                Log.d(TAG, "Step ${currentStep.id} executed successfully")
                stepIndex++
                taskStateManager.markStepCompleted(currentStep.id)
            } else {
                // 步骤执行失败
                Log.e(TAG, "Failed to execute step ${currentStep.id}")
                
                // 检查是否有备选步骤
                if (currentStep.fallbackSteps.isNotEmpty()) {
                    Log.d(TAG, "Trying fallback steps for ${currentStep.id}")
                    
                    // 查找备选步骤的索引
                    val fallbackStepId = currentStep.fallbackSteps.first()
                    val fallbackStepIndex = plan.steps.indexOfFirst { it.id == fallbackStepId }
                    
                    if (fallbackStepIndex >= 0) {
                        // 执行备选步骤
                        stepIndex = fallbackStepIndex
                        continue
                    }
                }
                
                // 没有有效的备选步骤，标记任务为失败
                _executionState.update { 
                    ExecutionState.Failed(plan, "步骤 '${currentStep.description}' 执行失败", stepIndex + 1) 
                }
                emit(_executionState.value)
                return@flow
            }
            
            // 检查是否完成所有步骤
            if (stepIndex >= plan.steps.size) {
                // 任务完成
                _executionState.update { ExecutionState.Completed(plan) }
                emit(_executionState.value)
                return@flow
            }
        }
    }
    
    /**
     * 执行单个步骤
     * 
     * @param step 要执行的步骤
     * @return 执行是否成功
     */
    private suspend fun executeStep(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        Log.d(TAG, "Executing step: ${step.description}")
        
        val timeout = step.timeoutMs ?: DEFAULT_TIMEOUT
        val startTime = System.currentTimeMillis()
        
        // 根据操作类型执行相应动作
        val success = when (step.actionType) {
            ExecutionStep.ActionType.APP_LAUNCH -> launchApp(step)
            ExecutionStep.ActionType.CLICK -> clickElement(step)
            ExecutionStep.ActionType.SWIPE -> swipeScreen(step)
            ExecutionStep.ActionType.ENTER_TEXT -> enterText(step)
            ExecutionStep.ActionType.WAIT -> wait(step)
            ExecutionStep.ActionType.SCREENSHOT -> takeScreenshot(step)
            ExecutionStep.ActionType.CHECK_ELEMENT -> checkElement(step)
            ExecutionStep.ActionType.BACK -> pressBack()
            ExecutionStep.ActionType.HOME -> pressHome()
            ExecutionStep.ActionType.CUSTOM -> executeCustomAction(step)
        }
        
        // 等待一段时间，让UI有时间响应
        delay(DEFAULT_WAIT_AFTER_ACTION)
        
        // 检查成功条件
        val successCriteriaCheck = checkSuccessCriteria(step)
        
        return@withContext success && successCriteriaCheck
    }
    
    /**
     * 启动应用
     */
    private suspend fun launchApp(step: ExecutionStep): Boolean = withContext(Dispatchers.Main) {
        try {
            val packageName = step.params?.get("packageName") as? String
                ?: return@withContext false
            
            val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
            if (launchIntent != null) {
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                context.startActivity(launchIntent)
                return@withContext true
            }
            return@withContext false
        } catch (e: Exception) {
            Log.e(TAG, "Failed to launch app", e)
            return@withContext false
        }
    }
    
    /**
     * 点击元素
     */
    private suspend fun clickElement(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            // 首先尝试通过元素描述查找元素
            val targetElementDesc = step.targetElement ?: return@withContext false
            val node = screenAnalyzer.findElement(targetElementDesc)
            
            if (node != null) {
                // 找到元素，点击它
                val clickResult = node.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                node.recycle()
                return@withContext clickResult
            } else {
                // 如果找不到元素，尝试使用坐标点击
                val x = step.params?.get("x") as? Int
                val y = step.params?.get("y") as? Int
                
                if (x != null && y != null) {
                    return@withContext performGestureClick(x, y)
                }
            }
            
            Log.e(TAG, "Cannot find element to click: $targetElementDesc")
            return@withContext false
        } catch (e: Exception) {
            Log.e(TAG, "Failed to click element", e)
            return@withContext false
        }
    }
    
    /**
     * 滑动屏幕
     */
    private suspend fun swipeScreen(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            val startX = step.params?.get("startX") as? Int ?: return@withContext false
            val startY = step.params?.get("startY") as? Int ?: return@withContext false
            val endX = step.params?.get("endX") as? Int ?: return@withContext false
            val endY = step.params?.get("endY") as? Int ?: return@withContext false
            val duration = step.params?.get("duration") as? Long ?: 300L
            
            return@withContext performGestureSwipe(startX, startY, endX, endY, duration)
        } catch (e: Exception) {
            Log.e(TAG, "Failed to swipe screen", e)
            return@withContext false
        }
    }
    
    /**
     * 输入文本
     */
    private suspend fun enterText(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            val text = step.params?.get("text") as? String ?: return@withContext false
            
            // 查找输入框
            val targetElementDesc = step.targetElement ?: return@withContext false
            val node = screenAnalyzer.findElement(targetElementDesc)
            
            if (node != null) {
                val bundle = Bundle()
                bundle.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text)
                val result = node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle)
                node.recycle()
                return@withContext result
            }
            
            Log.e(TAG, "Cannot find input element: $targetElementDesc")
            return@withContext false
        } catch (e: Exception) {
            Log.e(TAG, "Failed to enter text", e)
            return@withContext false
        }
    }
    
    /**
     * 等待一段时间或条件满足
     */
    private suspend fun wait(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            val waitTime = step.params?.get("waitTimeMs") as? Long
            
            if (waitTime != null) {
                // 简单等待指定时间
                delay(waitTime)
                return@withContext true
            }
            
            // 等待特定元素出现
            val waitForElement = step.params?.get("waitForElement") as? String
            if (waitForElement != null) {
                val timeout = step.timeoutMs ?: DEFAULT_TIMEOUT
                val startTime = System.currentTimeMillis()
                
                while (System.currentTimeMillis() - startTime < timeout) {
                    val element = screenAnalyzer.findElementByDescription(waitForElement)
                    if (element != null) {
                        element.recycle()
                        return@withContext true
                    }
                    delay(200) // 小延迟再检查
                }
                
                Log.e(TAG, "Timeout waiting for element: $waitForElement")
                return@withContext false
            }
            
            return@withContext true
        } catch (e: Exception) {
            Log.e(TAG, "Failed to wait", e)
            return@withContext false
        }
    }
    
    /**
     * 截图操作
     */
    private suspend fun takeScreenshot(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            if (mediaProjection == null) {
                Log.e(TAG, "Media projection not available for screenshot")
                return@withContext false
            }
            
            // 实际截图操作需要实现
            // 这里只是演示，返回成功
            Log.d(TAG, "Screenshot would be taken here with media projection")
            return@withContext true
        } catch (e: Exception) {
            Log.e(TAG, "Failed to take screenshot", e)
            return@withContext false
        }
    }
    
    /**
     * 检查元素是否存在
     */
    private suspend fun checkElement(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            val targetElementDesc = step.targetElement ?: return@withContext false
            val node = screenAnalyzer.findElement(targetElementDesc)
            
            val exists = node != null
            node?.recycle()
            
            return@withContext exists
        } catch (e: Exception) {
            Log.e(TAG, "Failed to check element", e)
            return@withContext false
        }
    }
    
    /**
     * 返回上一页
     */
    private suspend fun pressBack(): Boolean = withContext(Dispatchers.Main) {
        try {
            return@withContext accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
        } catch (e: Exception) {
            Log.e(TAG, "Failed to press back", e)
            return@withContext false
        }
    }
    
    /**
     * 返回主屏幕
     */
    private suspend fun pressHome(): Boolean = withContext(Dispatchers.Main) {
        try {
            return@withContext accessibilityService.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME)
        } catch (e: Exception) {
            Log.e(TAG, "Failed to press home", e)
            return@withContext false
        }
    }
    
    /**
     * 执行自定义操作
     */
    private suspend fun executeCustomAction(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        try {
            val actionName = step.params?.get("actionName") as? String ?: return@withContext false
            
            // 根据自定义操作名称执行相应逻辑
            when (actionName) {
                "openSettings" -> {
                    val intent = Intent(Settings.ACTION_SETTINGS)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    context.startActivity(intent)
                    return@withContext true
                }
                "openUrl" -> {
                    val url = step.params["url"] as? String ?: return@withContext false
                    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    context.startActivity(intent)
                    return@withContext true
                }
                // 更多自定义操作...
                else -> return@withContext false
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to execute custom action", e)
            return@withContext false
        }
    }
    
    /**
     * 检查步骤的成功条件
     */
    private suspend fun checkSuccessCriteria(step: ExecutionStep): Boolean = withContext(Dispatchers.Default) {
        // 如果没有成功条件，默认为成功
        if (step.successCriteria.isNullOrEmpty()) {
            return@withContext true
        }
        
        // 这里应该根据成功条件进行检查
        // 简单实现，未来可扩展更复杂的条件检查
        val successElement = step.params?.get("successElement") as? String
        
        if (successElement != null) {
            val node = screenAnalyzer.findElementByDescription(successElement)
            val found = node != null
            node?.recycle()
            return@withContext found
        }
        
        return@withContext true
    }
    
    /**
     * 执行手势点击
     */
    private fun performGestureClick(x: Int, y: Int): Boolean {
        val path = Path()
        path.moveTo(x.toFloat(), y.toFloat())
        
        val gestureBuilder = GestureDescription.Builder()
        val gesture = GestureDescription.StrokeDescription(path, 0, 10)
        gestureBuilder.addStroke(gesture)
        
        val result = accessibilityService.dispatchGesture(
            gestureBuilder.build(),
            object : AccessibilityService.GestureResultCallback() {
                override fun onCompleted(gestureDescription: GestureDescription) {
                    super.onCompleted(gestureDescription)
                    Log.d(TAG, "Gesture click completed at ($x, $y)")
                }
                
                override fun onCancelled(gestureDescription: GestureDescription) {
                    super.onCancelled(gestureDescription)
                    Log.e(TAG, "Gesture click cancelled at ($x, $y)")
                }
            },
            null
        )
        
        return result
    }
    
    /**
     * 执行手势滑动
     */
    private fun performGestureSwipe(startX: Int, startY: Int, endX: Int, endY: Int, duration: Long): Boolean {
        val path = Path()
        path.moveTo(startX.toFloat(), startY.toFloat())
        path.lineTo(endX.toFloat(), endY.toFloat())
        
        val gestureBuilder = GestureDescription.Builder()
        val gesture = GestureDescription.StrokeDescription(path, 0, duration)
        gestureBuilder.addStroke(gesture)
        
        val result = accessibilityService.dispatchGesture(
            gestureBuilder.build(),
            object : AccessibilityService.GestureResultCallback() {
                override fun onCompleted(gestureDescription: GestureDescription) {
                    super.onCompleted(gestureDescription)
                    Log.d(TAG, "Gesture swipe completed")
                }
                
                override fun onCancelled(gestureDescription: GestureDescription) {
                    super.onCancelled(gestureDescription)
                    Log.e(TAG, "Gesture swipe cancelled")
                }
            },
            null
        )
        
        return result
    }
    
    /**
     * 检查是否有所需的权限
     */
    private fun checkRequiredPermissions(permissions: List<String>): Boolean {
        // 在实际应用中应该检查每个权限
        // 这里简化实现，仅检查无障碍服务权限
        val isAccessibilityEnabled = isAccessibilityServiceEnabled()
        
        // 检查是否需要截图权限
        val needsScreenshotPermission = permissions.contains("android.permission.CAPTURE_VIDEO_OUTPUT")
        
        return isAccessibilityEnabled && (!needsScreenshotPermission || mediaProjection != null)
    }
    
    /**
     * 获取缺失的权限
     */
    private fun getMissingPermissions(permissions: List<String>): List<String> {
        val missingPermissions = mutableListOf<String>()
        
        // 检查无障碍服务
        if (!isAccessibilityServiceEnabled()) {
            missingPermissions.add("android.permission.BIND_ACCESSIBILITY_SERVICE")
        }
        
        // 检查截图权限
        if (permissions.contains("android.permission.CAPTURE_VIDEO_OUTPUT") && mediaProjection == null) {
            missingPermissions.add("android.permission.CAPTURE_VIDEO_OUTPUT")
        }
        
        return missingPermissions
    }
    
    /**
     * 检查无障碍服务是否启用
     */
    private fun isAccessibilityServiceEnabled(): Boolean {
        // 无障碍服务的实例已经传入，所以假设它已经启用
        return true
    }
    
    /**
     * 暂停当前任务执行
     */
    fun pauseExecution() {
        val currentState = _executionState.value
        if (currentState is ExecutionState.Executing) {
            _executionState.update { ExecutionState.Paused(currentState.plan, currentState.currentStepIndex) }
        }
    }
    
    /**
     * 恢复暂停的任务
     */
    fun resumeExecution() {
        val currentState = _executionState.value
        if (currentState is ExecutionState.Paused) {
            _executionState.update { ExecutionState.Executing(currentState.plan, currentState.stepIndex, currentState.plan.steps.size) }
            
            // 在协程中继续执行
            coroutineScope.launch {
                // 找到当前步骤索引
                val stepIndex = currentState.stepIndex - 1
                if (stepIndex >= 0 && stepIndex < currentState.plan.steps.size) {
                    // 从当前步骤继续执行
                    executeTaskPlan(currentState.plan)
                }
            }
        }
    }
    
    /**
     * 取消当前任务执行
     */
    fun cancelExecution() {
        val currentState = _executionState.value
        if (currentState is ExecutionState.Executing || currentState is ExecutionState.Paused) {
            _executionState.update { ExecutionState.Cancelled(currentState.plan) }
        }
    }
}

/**
 * 执行状态
 */
sealed class ExecutionState {
    /** 空闲状态，未执行任务 */
    object Idle : ExecutionState()
    
    /** 准备执行任务 */
    data class Preparing(val plan: TaskExecutionPlan) : ExecutionState()
    
    /** 执行中 */
    data class Executing(
        val plan: TaskExecutionPlan,
        val currentStepIndex: Int,
        val totalSteps: Int
    ) : ExecutionState()
    
    /** 已暂停 */
    data class Paused(val plan: TaskExecutionPlan, val stepIndex: Int) : ExecutionState()
    
    /** 已完成 */
    data class Completed(val plan: TaskExecutionPlan) : ExecutionState()
    
    /** 已失败 */
    data class Failed(val plan: TaskExecutionPlan, val errorMessage: String, val failedStepIndex: Int) : ExecutionState()
    
    /** 已取消 */
    data class Cancelled(val plan: TaskExecutionPlan) : ExecutionState()
    
    /** 需要权限 */
    data class PermissionsRequired(val permissions: List<String>) : ExecutionState()
} 